/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package systole.view.tabs.controllers;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Observable;
import java.util.Vector;
import systole.domain.analysis.Analysis;
import systole.domain.signals.Segment;
import systole.domain.signals.SelectedSegment;

/**
 * 
 * @author jmj
 */
public class SelectionModel extends Observable {

    private Collection<SelectedSegment> selectedSegments;
    private Vector<SelectionItem> currentSegments;
    private Vector<SelectionItem> originalSegments;
    private boolean modified;
    private boolean confirmed;
    private boolean dirty;
    private int amountOfSelected;

    /**
     * 
     */
    public SelectionModel() {
        this.selectedSegments = new ArrayList<SelectedSegment>();
        this.currentSegments = new Vector<SelectionItem>();
        this.originalSegments = new Vector<SelectionItem>();
        this.modified = false;
        this.confirmed = true;
        this.dirty = false;
        this.amountOfSelected = 0;
    }

    /**
     *
     * @return list of segment selected
     */
    public Collection<SelectionItem> getCurrentSegments() {
        return currentSegments;
    }

    /**
     *
     * @param item
     */
    public void addSegment(int item) {
        SelectionItem it = this.currentSegments.get(item);
        if ((it != null) && (!it.isSelected())) {
            it.setSelected(true);
            this.amountOfSelected++;
            this.markAsModified();
            this.setChanged();
            this.notifyObservers(it);
        }
    }

    /**
     *
     * @param item
     */
    public void removeSegment(int item) {
        SelectionItem it = this.currentSegments.get(item);
        if ((it != null) && (it.isSelected())) {
            it.setSelected(false);
            this.amountOfSelected--;
            this.markAsModified();
            this.setChanged();
            this.notifyObservers(it);
        }
    }

    /**
     * 
     */
    public void clearSelection() {
        if (!this.currentSegments.isEmpty()) {
            for (int i = 0; i < this.currentSegments.size(); i++) {
                this.currentSegments.get(i).setSelected(false);
            }
            this.amountOfSelected = 0;
            this.markAsModified();
            this.setChanged();
            this.notifyObservers(null);
        }
    }

    /**
     * @return the
     */
    public boolean isModified() {
        return modified;
    }

    /**
     * @return if there are any segment selected
     */
    public boolean isSelectionEmpty() {
        return !(this.amountOfSelected > 0);
    }

    /**
     * @return the amountOfSelected
     */
    public int getAmountOfSelected() {
        return amountOfSelected;
    }

    /**
     * @param analysis 
     */
    public void confirmModel(Analysis analysis) {
        if (!this.confirmed) {
            this.markAsConfirmed();
            this.markAsDirty();
            this.originalSegments.clear();
            this.originalSegments = (Vector<SelectionItem>) this.currentSegments.clone();
            this.getSelectedSegments().clear();
            // generate selected segments
            Iterator<SelectionItem> items = this.originalSegments.iterator();
            SelectionItem item;
            while (items.hasNext()) {
                item = items.next();
                if (item.isSelected()) {
                    Segment segment = analysis.getAllSegments().getSegments().elementAt(item.getIndexSegement());
                    if (segment != null) {
                        SelectedSegment selectedSegment = new SelectedSegment(item.getIndexSegement(), segment);
                        this.getSelectedSegments().add(selectedSegment);
                    }
                }
            }
        }
    }

    /**
     *
     * @param analysis
     * @param items
     */
    public void loadConfirmedSegments(Analysis analysis, Vector<SelectionItem> items) {
        this.originalSegments = items;
        this.currentSegments = (Vector<SelectionItem>) items.clone();
        this.selectedSegments = analysis.getSelectedSegments();
        Iterator<SelectionItem> itemsSeledted = this.originalSegments.iterator();
        while (itemsSeledted.hasNext()) {
            if (itemsSeledted.next().isSelected()) {
                this.amountOfSelected++;
            }
        }
        this.markAsConfirmed();
        this.dirty = false;
        this.setChanged();
        this.notifyObservers(null);
    }

    /**
     * @return the confirmed
     */
    public boolean isConfirmed() {
        return confirmed;
    }

    public void save() {
        if (this.dirty) {
            this.markAsConfirmed();
            this.dirty = false;
        }
    }

    /**
     * @return the originalSegments
     */
    public Vector<SelectionItem> getOriginalSegments() {
        return originalSegments;
    }

    /**
     * @return the dirty
     */
    public boolean isDirty() {
        return dirty;
    }

    /**
     *
     * @param items
     */
    public void loadSegments(Vector<SelectionItem> items) {
        this.originalSegments = items;
        this.currentSegments = (Vector<SelectionItem>) items.clone();
        this.notifyObservers(null);
    }

    /**
     * @return the selectedSegments
     */
    public Collection<SelectedSegment> getSelectedSegments() {
        return selectedSegments;
    }

    private void markAsDirty() {
        this.dirty = true;
    }

    private void markAsConfirmed() {
        this.confirmed = true;
        this.modified = false;
        this.markAsDirty();
    }

    private void markAsModified() {
        this.modified = true;
        this.confirmed = false;
    }

    public void revertModification() {
        this.currentSegments.clear();
        this.currentSegments = (Vector<SelectionItem>) this.originalSegments.clone();
        this.markAsConfirmed();
        this.setChanged();
        this.notifyObservers(null);
    }
}
